package GUI;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

import controller.InputOutputController;
import controller.MonteCarloSimulation;

public class MonteCarloGUI extends JFrame {

	/* */
	private JTextArea jTA;
	private JPanel jPS, jPC, jPW, jPN;
	private JComboBox profileComboBox;
	private JComboBox singleMultiComboBox;
	private JTextField nStepsField;
	private JTextField nSimulationsField;
	private double myResult;
	
	/* */
	public MonteCarloGUI(String title, int w, int h) {
		super(title);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.centerScreen(w, h);
		
		this.initialise();
		
		this.setVisible(true);
	}

	public MonteCarloGUI(String title, int w, int h, int x, int y) {
		super(title);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBounds(x, y, w, h);
		
		this.initialise();
		
		this.setVisible(true);
	}
	
	public MonteCarloGUI(String title, int w, int h, int i) {
		super(title);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.centerScreen(w, h);
		this.setVisible(true);
		
		this.initialise();
		
		this.setCursor(Cursor.getPredefinedCursor(i));
	}
	
	/* */
	private void centerScreen(int w, int h) {
		Toolkit aTK = Toolkit.getDefaultToolkit();
		Dimension dim = aTK.getScreenSize();
		int x = (dim.width / 2) - (w / 2);
		int y = (dim.height / 2) - (h / 2);
		this.setBounds(x, y, w, h);
	}
	
	/* */
	public void initialise() {
		this.setLayout(new BorderLayout());
		
		this.add(this.getPanelCenter(), BorderLayout.CENTER);
		this.add(this.getPanelNorth(), BorderLayout.NORTH);
		this.add(this.getPanelSouth(), BorderLayout.SOUTH);
		//
		this.add(this.getPanelWest(), BorderLayout.WEST);
	}
	
	private JPanel getPanelNorth() {
		GridLayout myGridLayout = new GridLayout(1, 1);
		jPN = new JPanel(myGridLayout);
		
		String[] singleMultiThread = {"Single", "Multi"};
		
		JLabel singleMultiLabel = new JLabel("Thread");
		this.jPN.add(singleMultiLabel);
		
		singleMultiComboBox = new JComboBox<>(singleMultiThread);
		this.jPN.add(singleMultiComboBox);
		
		return jPN;
	}
	
	private JPanel getPanelCenter() {
		jPC = new JPanel();
		jTA = new JTextArea();
		jPC.setLayout(new BorderLayout());
		this.jTA.setEditable(false);
		this.jPC.add(jTA, BorderLayout.CENTER);
		
		return jPC;
	}
	
	private JPanel getPanelWest() {
		GridLayout myGridLayout = new GridLayout(3, 2);
		jPW = new JPanel(myGridLayout);
		
		// Profile
		ArrayList<String> arrayProfile;
		try {
			arrayProfile = InputOutputController.readTickers();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			arrayProfile = new ArrayList<String>(); 
			e.printStackTrace();
		}
		
		JLabel profileLabel = new JLabel("Profile");
		this.jPW.add(profileLabel);
		profileComboBox = new JComboBox<>(arrayProfile.toArray());
		this.jPW.add(profileComboBox);
		
		// nSteps
		JLabel nSteps = new JLabel("nSteps");
		this.jPW.add(nSteps);
		nStepsField = new JTextField();
		this.jPW.add(nStepsField);
		
		// nSimulations
		JLabel nSimulations = new JLabel("nSimulations");
		this.jPW.add(nSimulations);
		nSimulationsField = new JTextField();
		this.jPW.add(nSimulationsField);
		
		return jPW;
	}
	
	private JPanel getPanelSouth() {
		jPS = new JPanel();
		
		String start = new String("Start");
		String stop = new String("Stop");
		
		JButton startButton = new JButton(start);
		JButton stopButton = new JButton(stop);
		
		jPS.setLayout(new FlowLayout());
		
		StartListener startAction = new StartListener();
		startButton.addActionListener(startAction);
		
		StopListener stopAction = new StopListener();
		stopButton.addActionListener(stopAction);
		
		this.jPS.add(startButton);
		//this.jPS.add(stopButton);
		
		return jPS;
	}
	
	/**
	 * 
	 * * * * * * * * * * * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *  * * *    
	 *
	 */
	
	class StartListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String profile = (String) profileComboBox.getSelectedItem();
			String singleMulti = (String) singleMultiComboBox.getSelectedItem();
			
			StringTokenizer st = new StringTokenizer(profile, ",");

			String CallPutFlag = st.nextToken();
			double S = Double.parseDouble(st.nextToken());
			double X = Double.parseDouble(st.nextToken());
			double T = Double.parseDouble(st.nextToken());
			double r = Double.parseDouble(st.nextToken());
			double b = Double.parseDouble(st.nextToken());
			double v = Double.parseDouble(st.nextToken());
			
			if (singleMulti.equals("Single")) {
				long departTime = System.nanoTime();
				myResult = MonteCarloSimulation.MonteCarloStandardOption(CallPutFlag, S, X, T, r, b, v, Integer.parseInt(nStepsField.getText()), 
						Integer.parseInt(nSimulationsField.getText()));
				long arrivalTime = System.nanoTime();
				jTA.append("My result : " + myResult + "\n");
				jTA.append("Time execution is (sec) = " + ((arrivalTime - departTime) / Math.pow(1, 9)) + "\n");
			}
			else {
				long departTime = System.nanoTime();
				try {
					myResult = MonteCarloSimulation.MonteCarloMultiThreads(CallPutFlag, S, X, T, r, b, v, Integer.parseInt(nStepsField.getText()), 
							Integer.parseInt(nSimulationsField.getText()));
				} catch (NumberFormatException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (ExecutionException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				long arrivalTime = System.nanoTime();
				jTA.append("My result : " + myResult + "\n");
				jTA.append("Time execution is (sec) = " + ((arrivalTime - departTime) / Math.pow(1, 9)) + "\n");
			}
		}
	}
	
	class StopListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = 3;
		
		Toolkit aTK = Toolkit.getDefaultToolkit();
		Dimension dim = aTK.getScreenSize();
		
		//int h = (dim.height / n);
		//int w = (dim.width / n);
		
		new MonteCarloGUI("MonteCarlo", 800, 600);

	}

}
